from fastapi import APIRouter, Request, HTTPException, Query
import uuid
import time
from urllib.parse import urlparse
from typing import Optional

from service.video_audio_service import VideoAudioService
from mrouter.domain.WxCloudRunHeader import WxCloudRunHeader
from utils.response import create_response
from utils.request_context import RequestContext, context_logger
from config.logging_config import ProjectLoggers
from config.video_config import VIDEO_CONFIG
from dto.video_request import VideoUploadRequest, TaskCancelRequest
from dto.video_response import (
    VideoUploadResponse, TaskStatusResponse, UserTasksResponse, 
    AudioDownloadResponse, SupportedFormatsResponse, SystemStatusResponse,
    TaskOperationResponse
)

logger = ProjectLoggers.get_service_logger()
router = APIRouter(prefix="/video", tags=["视频处理"])

# 创建服务实例
video_service = VideoAudioService()

@router.post("/parseToAudio", response_model=VideoUploadResponse)
async def upload_video(
    request: Request,
    upload_request: VideoUploadRequest
):
    """
    通过视频链接创建音频转换任务
    
    - **video_url**: 视频文件URL（七牛云链接）
    - **original_filename**: 原始文件名（可选，为空时自动生成UUID文件名）
    - **audio_format**: 音频输出格式（支持 mp3, wav, aac, ogg, flac）
    """
    # 设置请求上下文
    request_id = RequestContext.generate_request_id()
    RequestContext.set_request_id(request_id)
    
    # 记录请求开始时间和日志
    start_time = time.perf_counter()
    user_openid = await WxCloudRunHeader.get_openid(request)
    
    # 截断URL显示，避免日志过长
    display_url = upload_request.video_url[:100] + ('...' if len(upload_request.video_url) > 100 else '')
    context_logger.info(f"🎵 开始视频转音频任务 - URL: {display_url}, 格式: {upload_request.audio_format}, 质量: {upload_request.audio_quality}, 用户: {user_openid or '未知'}")
    
    try:
        # 如果没有提供文件名，生成一个默认的
        original_filename = upload_request.original_filename
        if not original_filename:
            # 尝试从URL中提取文件扩展名
            parsed_url = urlparse(upload_request.video_url)
            path = parsed_url.path
            if path and '.' in path:
                ext = path.split('.')[-1].lower()
                # 验证是否为支持的视频格式
                if ext in [fmt.lower() for fmt in VIDEO_CONFIG["supported_video_formats"]]:
                    original_filename = f"{str(uuid.uuid4())[:8]}.{ext}"
                else:
                    original_filename = f"{str(uuid.uuid4())[:8]}.mp4"  # 默认使用mp4
            else:
                original_filename = f"{str(uuid.uuid4())[:8]}.mp4"  # 默认使用mp4
        
        context_logger.info(f"📁 文件名处理完成: {original_filename}")
        
        # 调用服务处理  
        service_start_time = time.perf_counter()
        result = await video_service.create_task_from_url(
            video_url=upload_request.video_url,
            original_filename=original_filename,
            user_openid=user_openid,
            audio_format=upload_request.audio_format,
            audio_quality=upload_request.audio_quality
        )
        
        service_elapsed = time.perf_counter() - service_start_time
        total_elapsed = time.perf_counter() - start_time
        
        if result["success"]:
            task_id = result["data"]["task_id"]
            context_logger.info(f"✅ 视频转音频任务创建成功 - 任务ID: {task_id}, 服务耗时: {service_elapsed:.3f}秒, 总耗时: {total_elapsed:.3f}秒")
            
            return create_response(
                code=200,
                msg="任务创建成功",
                data=result["data"]
            )
        else:
            context_logger.error(f"❌ 视频转音频任务创建失败 - 错误: {result['error']}, 服务耗时: {service_elapsed:.3f}秒, 总耗时: {total_elapsed:.3f}秒")
            return create_response(
                code=400,
                msg=result["error"]
            )
            
    except Exception as e:
        elapsed_time = time.perf_counter() - start_time
        context_logger.error(f"❌ 视频转音频接口异常，耗时: {elapsed_time:.3f}秒 - {str(e)}", exc_info=True)
        return create_response(code=500, msg=f"服务器内部错误: {str(e)}")

@router.get("/task/{task_id}", response_model=TaskStatusResponse)
async def get_task_status(task_id: str):
    """
    获取任务状态
    
    - **task_id**: 任务ID
    """
    # 设置请求上下文
    request_id = RequestContext.generate_request_id()
    RequestContext.set_request_id(request_id)
    
    # 记录请求开始时间和日志
    start_time = time.perf_counter()
    context_logger.info(f"🔍 查询任务状态 - 任务ID: {task_id}")
    
    try:
        result = await video_service.get_task_status(task_id)
        elapsed_time = time.perf_counter() - start_time
        
        if result["success"]:
            task_status = result["data"]["status"]
            context_logger.info(f"✅ 任务状态查询成功 - 任务ID: {task_id}, 状态: {task_status}, 耗时: {elapsed_time:.3f}秒")
            return create_response(
                code=200,
                msg="获取任务状态成功",
                data=result["data"]
            )
        else:
            context_logger.warning(f"⚠️ 任务状态查询失败 - 任务ID: {task_id}, 错误: {result['error']}, 耗时: {elapsed_time:.3f}秒")
            return create_response(code=404, msg=result["error"])
            
    except Exception as e:
        elapsed_time = time.perf_counter() - start_time
        context_logger.error(f"❌ 任务状态查询异常 - 任务ID: {task_id}, 耗时: {elapsed_time:.3f}秒 - {str(e)}", exc_info=True)
        return create_response(code=500, msg=f"服务器内部错误: {str(e)}")

@router.get("/tasks", response_model=UserTasksResponse)
async def get_user_tasks(
    request: Request,
    page: int = Query(1, ge=1, description="页码"),
    page_size: int = Query(20, ge=1, le=100, description="每页数量")
):
    """
    获取用户的任务列表（分页）
    
    - **page**: 页码，从1开始
    - **page_size**: 每页数量，最大100
    """
    # 设置请求上下文
    request_id = RequestContext.generate_request_id()
    RequestContext.set_request_id(request_id)
    
    # 记录请求开始时间和日志
    start_time = time.perf_counter()
    user_openid = await WxCloudRunHeader.get_openid(request)
    context_logger.info(f"📋 查询用户任务列表 - 用户: {user_openid or '未知'}, 页码: {page}, 每页: {page_size}")
    
    try:
        if not user_openid:
            context_logger.warning(f"⚠️ 用户任务列表查询失败 - 错误: 用户身份验证失败")
            return create_response(code=401, msg="用户身份验证失败")
        
        result = await video_service.get_user_tasks(user_openid, page, page_size)
        elapsed_time = time.perf_counter() - start_time
        
        if result["success"]:
            task_count = result["data"]["pagination"]["total"]
            context_logger.info(f"✅ 用户任务列表查询成功 - 用户: {user_openid}, 总任务数: {task_count}, 耗时: {elapsed_time:.3f}秒")
            return create_response(
                code=200,
                msg="获取任务列表成功",
                data=result["data"]
            )
        else:
            context_logger.error(f"❌ 用户任务列表查询失败 - 用户: {user_openid}, 错误: {result['error']}, 耗时: {elapsed_time:.3f}秒")
            return create_response(code=500, msg=result["error"])
            
    except Exception as e:
        elapsed_time = time.perf_counter() - start_time
        context_logger.error(f"❌ 用户任务列表查询异常 - 用户: {user_openid or '未知'}, 耗时: {elapsed_time:.3f}秒 - {str(e)}", exc_info=True)
        return create_response(code=500, msg=f"服务器内部错误: {str(e)}")

@router.post("/task/{task_id}/cancel", response_model=TaskOperationResponse)
async def cancel_task(task_id: str):
    """
    取消任务
    
    - **task_id**: 任务ID
    """
    # 设置请求上下文
    request_id = RequestContext.generate_request_id()
    RequestContext.set_request_id(request_id)
    
    # 记录请求开始时间和日志
    start_time = time.perf_counter()
    context_logger.info(f"🛑 取消任务 - 任务ID: {task_id}")
    
    try:
        result = await video_service.cancel_task(task_id)
        elapsed_time = time.perf_counter() - start_time
        
        if result["success"]:
            context_logger.info(f"✅ 任务取消成功 - 任务ID: {task_id}, 耗时: {elapsed_time:.3f}秒")
            return create_response(
                code=200,
                msg="任务已取消",
                data={"task_id": task_id, "status": "cancelled"}
            )
        else:
            context_logger.warning(f"⚠️ 任务取消失败 - 任务ID: {task_id}, 错误: {result['error']}, 耗时: {elapsed_time:.3f}秒")
            return create_response(code=400, msg=result["error"])
            
    except Exception as e:
        elapsed_time = time.perf_counter() - start_time
        context_logger.error(f"❌ 任务取消异常 - 任务ID: {task_id}, 耗时: {elapsed_time:.3f}秒 - {str(e)}", exc_info=True)
        return create_response(code=500, msg=f"服务器内部错误: {str(e)}")

@router.delete("/task/{task_id}", response_model=TaskOperationResponse)
async def delete_task(task_id: str):
    """
    删除任务
    
    - **task_id**: 任务ID
    """
    # 设置请求上下文
    request_id = RequestContext.generate_request_id()
    RequestContext.set_request_id(request_id)
    
    # 记录请求开始时间和日志
    start_time = time.perf_counter()
    context_logger.info(f"🗑️ 删除任务 - 任务ID: {task_id}")
    
    try:
        result = await video_service.delete_task(task_id)
        elapsed_time = time.perf_counter() - start_time
        
        if result["success"]:
            context_logger.info(f"✅ 任务删除成功 - 任务ID: {task_id}, 耗时: {elapsed_time:.3f}秒")
            return create_response(
                code=200,
                msg="任务已删除",
                data={"task_id": task_id, "status": "deleted"}
            )
        else:
            context_logger.warning(f"⚠️ 任务删除失败 - 任务ID: {task_id}, 错误: {result['error']}, 耗时: {elapsed_time:.3f}秒")
            return create_response(code=400, msg=result["error"])
            
    except Exception as e:
        elapsed_time = time.perf_counter() - start_time
        context_logger.error(f"❌ 任务删除异常 - 任务ID: {task_id}, 耗时: {elapsed_time:.3f}秒 - {str(e)}", exc_info=True)
        return create_response(code=500, msg=f"服务器内部错误: {str(e)}")

@router.get("/download/{task_id}", response_model=AudioDownloadResponse)
async def download_audio(task_id: str):
    """
    获取音频下载链接
    
    - **task_id**: 任务ID
    """
    # 设置请求上下文
    request_id = RequestContext.generate_request_id()
    RequestContext.set_request_id(request_id)
    
    # 记录请求开始时间和日志
    start_time = time.perf_counter()
    context_logger.info(f"📁 获取音频下载链接 - 任务ID: {task_id}")
    
    try:
        result = await video_service.get_task_status(task_id)
        elapsed_time = time.perf_counter() - start_time
        
        if not result["success"]:
            context_logger.warning(f"⚠️ 音频下载链接获取失败 - 任务ID: {task_id}, 错误: 任务不存在, 耗时: {elapsed_time:.3f}秒")
            return create_response(code=404, msg="任务不存在")
        
        task_data = result["data"]
        
        if task_data["status"] != "completed":
            context_logger.warning(f"⚠️ 音频下载链接获取失败 - 任务ID: {task_id}, 错误: 任务未完成({task_data['status']}), 耗时: {elapsed_time:.3f}秒")
            return create_response(code=400, msg="任务未完成，无法下载")
        
        if not task_data["audio_url"]:
            context_logger.warning(f"⚠️ 音频下载链接获取失败 - 任务ID: {task_id}, 错误: 音频文件不存在, 耗时: {elapsed_time:.3f}秒")
            return create_response(code=400, msg="音频文件不存在")
        
        context_logger.info(f"✅ 音频下载链接获取成功 - 任务ID: {task_id}, 格式: {task_data['audio_format']}, 耗时: {elapsed_time:.3f}秒")
        
        return create_response(
            code=200,
            msg="获取下载链接成功",
            data={
                "task_id": task_id,
                "original_filename": task_data["original_filename"],
                "audio_url": task_data["audio_url"],
                "audio_format": task_data["audio_format"],
                "duration": task_data["duration"],
                "file_size": task_data["file_size"]
            }
        )
        
    except Exception as e:
        elapsed_time = time.perf_counter() - start_time
        context_logger.error(f"❌ 音频下载链接获取异常 - 任务ID: {task_id}, 耗时: {elapsed_time:.3f}秒 - {str(e)}", exc_info=True)
        return create_response(code=500, msg=f"服务器内部错误: {str(e)}")

@router.get("/formats", response_model=SupportedFormatsResponse)
async def get_supported_formats():
    """
    获取支持的文件格式
    """
    try:
        from config.video_config import VIDEO_CONFIG
        
        return create_response(
            code=200,
            msg="获取支持格式成功",
            data={
                "video_formats": VIDEO_CONFIG["supported_video_formats"],
                "audio_formats": VIDEO_CONFIG["supported_audio_formats"],
                "max_file_size": VIDEO_CONFIG["max_file_size"],
                "max_file_size_display": f"{VIDEO_CONFIG['max_file_size'] // (1024*1024)}MB"
            }
        )
        
    except Exception as e:
        logger.error(f"获取支持格式接口异常: {str(e)}")
        return create_response(code=500, msg=f"服务器内部错误: {str(e)}")

@router.get("/system/status", response_model=SystemStatusResponse)
async def get_system_status():
    """
    获取系统状态信息
    """
    try:
        from utils.ffmpeg_helper import FFmpegHelper
        from utils.file_helper import FileHelper
        from config.video_config import VIDEO_CONFIG
        
        # 检查FFmpeg是否可用
        ffmpeg_available = FFmpegHelper.check_ffmpeg_available()
        
        # 获取当前处理中的任务数量
        processing_count = len(video_service.processing_tasks)
        
        # 清理临时目录
        cleaned_files = FileHelper.cleanup_temp_directory()
        
        return create_response(
            code=200,
            msg="获取系统状态成功",
            data={
                "ffmpeg_available": ffmpeg_available,
                "processing_tasks_count": processing_count,
                "max_concurrent_tasks": VIDEO_CONFIG["max_concurrent_tasks"],
                "temp_files_cleaned": cleaned_files,
                "system_healthy": ffmpeg_available
            }
        )
        
    except Exception as e:
        logger.error(f"获取系统状态接口异常: {str(e)}")
        return create_response(code=500, msg=f"服务器内部错误: {str(e)}")